// 
// Basic syntax test, this should be translated in/from JooScript (deprecated syntax)
//
$Unit(__PATH__, __FILE__, function(u,r,g){

    // we will operate in strict context to catch all errors
    "use strict";

    // import
    u.Import("a.b.c.*", "d.e.f")

    // fixme a.b.c.
    u.Package("a.b.c.", function(g){
        
        this.addClass(__PUBLIC__, // declare class in the group a.b.c

            u.buildClass( // build class
                "abc",  // class name
                [u.A, r.B, g.C],   // ancestors
                function(c){ // class body
                    //
                    // actual class constructor
                    this.__add__(__PUBLIC__, "__new__", function(self, a, b){ 
                        self.a = a
                        self[b] = b
                    }, null, Void)

                    // public property, not overrided
                    c.__add__(0, "a", 1, u.Int)

                    // public property with implicit type, overrided
                    c.__set__(__PUBLIC__, "b")

                    // internal z
                    c.__add__(__HIDDEN__ | __FROZEN__ | __SEALED__, "z", null, u.Float)

                    // props list
                    c.__set__(__PUBLIC__ | __FROZEN__, 
                                ["c", "x", "y", "foo", "bar"], 
                                [3, 4, 5, function(self){}, null], 
                                [Uint, Int, Float, Function, null])

                    // public lambda function
                    // todo: product type
                    c.__add__(__STATIC__, "baz", function(self,x){return x*x})

                    // hidden property, overrided
                    c.__add__(__HIDDEN__, "setXY", function(self, a, b, __rest__){
                        self.x = self.a
                        self.y = self.b
                        self.z = __rest__[0]
                    })

                   // delete class prop, this must raise an error, because of z is sealed
                   try {
                       c.__del__("z")
                   } catch(e) {
                       trace(e)
                   }

                   // Call class method. Due to different internal mechanics, it
                   // not possible to call class methods as usual, so we have to use call 
                   // wrapper.
                   // Note that I use method __set__, __add__ will raise an exception
                   // in this case, because of we have defined "a" above.
                   
                   this.__set__(0, "a", 
                        // first argument is a method name, second is context, last one is "x"
                        this.__call__("baz", this, 2))

                   // second example
                   this.__call__("setXY", this, 123, 456, 789)

                   // By the same reasons just this.<prop> will not work, we have to use
                   // __get__ method to make sure it will work in IE too.
                   // It is possible to use getters in modest browsers, but in IE this
                   // code will not work. 
                   // Good news is that compiler do care about this for you. So relax and
                   // write code as usual.

                   this.__set__(__PUBLIC__, "b", this.__get__("y"))

            })
        );
    })

    $Package("d.e.f", function(){
        $buildClass("def", null, function(z){
            
        })
    })

    var test = $buildClass(null, null, null)

    function JSClass() {
    }

    var foo = new JSClass
    var bar = new JSClass("abc")

    // in jooscript "!", "&&" and "||" is "not", "and" and "or" respectively
    if( a && b || !c )
        test()
    else {
        // empty
    }
})

